package general;

class Component
{

    public var id : Int;
    public var groupid : Int;
    public var componenttype : Int;
    public var data : Array<Dynamic>;


    public static var nextid : Int = 1;
    public static var allid : IntHash<Component> = new IntHash();
    public static var allgroup : IntHash<IntHash<Component>> = new IntHash();
    public static var alltype : IntHash<List<Component>> = new IntHash();

    // UNTESTED:

    public function new(componenttype : Int, groupid : Int)
    {

        //// set the component type; add it to the list
        /// of components of this type

        this.componenttype = componenttype;

        var typelist : List<Component>;

        if (alltype.exists(componenttype))
        {
            typelist = alltype.get(componenttype);
        }
        else
        {
            typelist = new List();
            alltype.set(componenttype, typelist);
        }
        typelist.add(this);

        //// set the component id; add it to the list of all
        /// components (max # of components limited by size of int)

        var count = 0;
        while (allid.exists(nextid) && nextid!=0)
        {
            nextid++;
            count++;
            if (count==0)
                throw "too many objects: count overflowed";
        }
        this.id = nextid;
        nextid++;

        //// if a group was specified use that, otherwise
        /// assign this to a new group;
        /// this *should* be unique because it's coupled with
        /// free component ids. fingers crossed

        var mygroup : IntHash<Component>;
        if (groupid==0)
        {
            mygroup = new IntHash();
            allgroup.set(this.id, mygroup);
            this.groupid = this.id;
        }
        else
        {
            mygroup = allgroup.get(groupid);
            this.groupid = groupid;
        }

    }

    // UNTESTED:

    public function copy(id : Int) : Component
    {
        var ret : Component;
        if (id==0)
            ret = new Component(0, 0);
        else
            ret = new Component(id, 0);
        switch(this.componenttype)
        {
            case(general.components.SimpleMovable.typeid):
                general.components.SimpleMovable.copy(this, ret);
        }
        return ret;
    }

    // UNTESTED:

    public function copygroup() : Int
    {

        // we pass along the groupid to every component copied
        // from the old group; the first generates because it's
        // null, the others reuse that id.

        var newgroupid : Int = 0;
        for (n in allgroup.get(this.groupid))
        {
            var newcomp = n.copy(newgroupid);
            newgroupid = newcomp.groupid;
        }
        return newgroupid;
    }

    // UNTESTED:

    public function delete()
    {
        this.data = null;
        allid.remove(this.id);
        allgroup.remove(this.groupid);
        var typelist = alltype.get(this.componenttype);
        typelist.remove(this);
    }

    // UNTESTED:

    public function deletegroup()
    {
        var group = allgroup.get(this.groupid);
        for (n in group)
            n.delete();
    }

}